﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace NoNameGoServer.Client.Gui {
    public partial class GoBoardUserControl : UserControl {
        private int _boardSize;
        private Pen _linePen;
        private int _lettersWidth;
        private int _lettersHeight;
        private Font _rowColumnFont;
        private Brush _rowColumnBrush;
        private StoneColor?[,] _stones;
        private Brush _brushWhite;
        private Brush _brushBlack;

        public delegate void IntersectionClickedDelegate(GoBoardUserControl sender, char letter, int number);
        public event IntersectionClickedDelegate IntersectionClicked;

        public GoBoardUserControl() {
            InitializeComponent();
            BoardSize = 19;
        }

        public int BoardSize {
            get { return _boardSize; }
            set {
                _boardSize = value;
                _stones = new StoneColor?[_boardSize, _boardSize];
                Invalidate();
            }
        }

        private void GoBoardUserControl_Paint(object sender, PaintEventArgs e) {
            if (_brushWhite == null) {
                _brushWhite = new SolidBrush(Color.White);
            }
            if (_brushBlack == null) {
                _brushBlack = new SolidBrush(Color.Black);
            }
            if (_linePen == null) {
                _linePen = new Pen(this.ForeColor);
            }
            if (_rowColumnFont == null) {
                _rowColumnFont = this.Font;
            }
            if (_rowColumnBrush == null) {
                _rowColumnBrush = new SolidBrush(this.ForeColor);
            }

            SizeF rowColumnSize = e.Graphics.MeasureString("A", _rowColumnFont);
            _lettersHeight = (int)rowColumnSize.Height + SquareSize;
            _lettersWidth = (int)rowColumnSize.Width + SquareSize;

            for (int y = 0; y < _boardSize; y++) {
                Point pt = GetIntersectionPoint(0, y);
                pt.X -= _lettersWidth;
                pt.Y -= _lettersHeight / 2 - (SquareSize / 2);
                e.Graphics.DrawString(string.Format("{0}", y + 1), _rowColumnFont, _rowColumnBrush, pt);
            }

            for (int x = 0; x < _boardSize; x++) {
                Point pt = GetIntersectionPoint(x, 0);
                pt.X -= _lettersWidth / 2 - (SquareSize / 2);
                pt.Y -= _lettersHeight;
                e.Graphics.DrawString("" + NNGSClient.LETTERS[x], _rowColumnFont, _rowColumnBrush, pt);
            }

            for (int y = 0; y < _boardSize; y++) {
                Point pt1 = GetIntersectionPoint(0, y);
                Point pt2 = GetIntersectionPoint(_boardSize - 1, y);
                e.Graphics.DrawLine(_linePen, pt1, pt2);
            }

            for (int x = 0; x < _boardSize; x++) {
                Point pt1 = GetIntersectionPoint(x, 0);
                Point pt2 = GetIntersectionPoint(x, _boardSize - 1);
                e.Graphics.DrawLine(_linePen, pt1, pt2);
            }

            for (int y = 0; y < _boardSize; y++) {
                for (int x = 0; x < _boardSize; x++) {
                    StoneColor? stone = _stones[x, y];
                    if (stone != null) {
                        Point pt = GetIntersectionPoint(x, y);
                        int squareSize = SquareSize;
                        int rx = pt.X - squareSize / 2;
                        int ry = pt.Y - squareSize / 2;
                        int rw = squareSize;
                        int rh = squareSize;
                        e.Graphics.FillEllipse(stone == StoneColor.White ? _brushWhite : _brushBlack, rx, ry, rw, rh);
                    }
                }
            }
        }

        private int SquareSize {
            get {
                int boardWidth = ClientSize.Width - _lettersWidth;
                int boardHeight = ClientSize.Height - _lettersHeight;
                int squareWidth = boardWidth / _boardSize;
                int squareHeight = boardHeight / _boardSize;
                return Math.Min(squareHeight, squareWidth);
            }
        }

        private Point GetIntersectionPoint(int x, int y) {
            int squareSize = SquareSize;
            int rx = _lettersWidth + (squareSize * x);
            int ry = _lettersHeight + (squareSize * y);
            return new Point(rx, ry);
        }

        private Point GetClosestSquare(int x, int y) {
            int squareSize = SquareSize;
            int rx = (int)Math.Round(((double)(x - _lettersWidth)) / ((double)squareSize));
            int ry = (int)Math.Round(((double)(y - _lettersHeight)) / ((double)squareSize));
            return new Point(rx, ry);
        }

        private void GoBoardUserControl_MouseClick(object sender, MouseEventArgs e) {
            Point pt = GetClosestSquare(e.X, e.Y);
            IntersectionClicked(this, NNGSClient.LETTERS[pt.X], pt.Y);
        }

        public void SetIntersection(char letter, int number, StoneColor? color) {
            _stones[NNGSClient.LETTERS.IndexOf(letter), number] = color;
            Invalidate();
        }
    }
}
